/*
  这个服务是将新增页面中的加减项中所需方法抽离出来，本来这种功能更适合在 class 基类中来完成；
  但是不是所有的页面都需要这部分功能，并且各个基类的所在文件层级不同，综合考虑，使用 service 来做这个抽离；
  在调用时，只需要在目标组件初始化时执行 init(func, obj, dataArr) 方法，
  func 是生成校验规则的方法，obj 是实例，dataArr 是传入的已存在的数据.
*/
import { Injectable, Inject } from '@angular/core'
import { FormGroup, FormBuilder } from '@angular/forms'
import { ExchangeRate } from '@shared/interfaces/acquirer'
import { deepCopy } from '@delon/util'
import { User } from '@shared/interfaces/user'
import { EventEmitter } from 'events'
import { Subject } from 'rxjs'
import { makeAllControlDirty } from 'app/utils/helpers'

@Injectable()
export class AddMinusService {

  eventEmitter = new EventEmitter()
  validateForms: FormGroup[] = []

  validateRules: { [key: string]: any }

  generateFunc: () => any[]

  obj: ExchangeRate | User

  isInitOne = true // 默认初始化的时候设置一个

  minusEvent$ = new Subject()

  constructor(
    public fb: FormBuilder,
  ) {}

  get values(): any[] {
    return this.validateForms.map(form => form.value)
  }

  get valid(): boolean {
    let isValid = true
    this.validateForms.forEach(form => isValid = form.valid ? isValid : false)
    return isValid
  }

  init(func, obj, dataArr) {
    this.generateFunc = func
    this.obj = obj
    if (dataArr.length > 0) {
      dataArr.forEach(data => this.generateForm(data))
    } else if (this.isInitOne) {
      this.generateForm(deepCopy(this.obj))
    }
  }

  generateForm(data) {
    const rule = this.generateFunc.call(this, data)
    const validateForm = this.fb.group(rule[0], rule[1])
    this.validateForms.push(validateForm)
  }

  addItem() {
    this.generateForm(deepCopy(this.obj))
    this.eventEmitter.emit('add')
  }

  minusItem(index: number) {
    if (this.validateForms.length === 0) { return }
    this.removeItem(index)
    this.validateForms.forEach(form => makeAllControlDirty(form))
  }

  removeItem(index: number) {
    if (this.validateForms.length === 0) return
    this.validateForms.forEach((form, i) => {
      if (i === index) {
        this.validateForms.splice(i, 1)
        this.minusEvent$.next(i)
      }
    })
  }
}
